#!/usr/bin/env python3
"""
Feng Admin 统一 API 服务
整合所有工具的后端接口
"""

from flask import Flask, jsonify
from flask_cors import CORS
from flask_jwt_extended import JWTManager
from werkzeug.exceptions import HTTPException
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger
import sys
import os
import atexit

# 添加路径以便导入其他模块
sys.path.append(os.path.dirname(os.path.dirname(__file__)))

# 导入配置和模型
from config import Config
from models import db

app = Flask(__name__)
app.config.from_object(Config)
Config.init_app(app)

# 禁用严格的斜杠要求，避免CORS预检请求被重定向
app.url_map.strict_slashes = False

# 初始化扩展
CORS(app, 
     resources={r"/api/*": {"origins": Config.CORS_ORIGINS}},
     supports_credentials=True,
     allow_headers=["Content-Type", "Authorization"],
     methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"])
db.init_app(app)
jwt = JWTManager(app)

# 配置SQLite引擎选项
if hasattr(Config, 'SQLALCHEMY_ENGINE_OPTIONS'):
    app.config['SQLALCHEMY_ENGINE_OPTIONS'] = Config.SQLALCHEMY_ENGINE_OPTIONS

# JWT 错误处理器 - 返回 JSON 而不是重定向
@jwt.unauthorized_loader
def unauthorized_callback(callback):
    print(f"[JWT ERROR] Unauthorized: {callback}")
    return jsonify({
        'error': 'Missing or invalid authentication token',
        'message': '未提供认证令牌或令牌无效'
    }), 401

@jwt.invalid_token_loader
def invalid_token_callback(callback):
    print(f"[JWT ERROR] Invalid token: {callback}")
    return jsonify({
        'error': 'Invalid authentication token',
        'message': '无效的认证令牌'
    }), 401

@jwt.expired_token_loader
def expired_token_callback(jwt_header, jwt_payload):
    print(f"[JWT ERROR] Expired token: {jwt_payload}")
    return jsonify({
        'error': 'Token has expired',
        'message': '认证令牌已过期'
    }), 401

@jwt.revoked_token_loader
def revoked_token_callback(jwt_header, jwt_payload):
    print(f"[JWT ERROR] Revoked token: {jwt_payload}")
    return jsonify({
        'error': 'Token has been revoked',
        'message': '认证令牌已被撤销'
    }), 401

# 导入各个工具的路由
from routes import github_trending, auth, todos, agents, notes, about, ai_dairy, excel_viewer, contacts, email_accounts, email_messages, ai_prompts
from routes import require_roles  # 可选导入，若不可用则为 None

# 注册蓝图（受功能开关控制）
if Config.FEATURE_AUTH:
    app.register_blueprint(auth.bp, url_prefix='/api/auth')
if Config.FEATURE_CRUD:
    app.register_blueprint(todos.bp, url_prefix='/api/todos')
    app.register_blueprint(notes.bp, url_prefix='/api/notes')
    app.register_blueprint(contacts.bp, url_prefix='/api/contacts')
    app.register_blueprint(email_accounts.accounts_bp, url_prefix='/api/email-accounts')
    app.register_blueprint(email_messages.messages_bp, url_prefix='/api/email-messages')
# 智能体与 AI
if Config.FEATURE_AI:
    app.register_blueprint(agents.bp, url_prefix='/api/agents')
    app.register_blueprint(ai_dairy.bp, url_prefix='/api/ai_dairy')
# GitHub Trending
if Config.FEATURE_GH_TRENDING:
    app.register_blueprint(github_trending.bp, url_prefix='/api/github')
# Excel
if Config.FEATURE_EXCEL:
    app.register_blueprint(excel_viewer.bp, url_prefix='/api/excel-viewer')
if Config.FEATURE_CRAWLER:
    from routes import crawler
    app.register_blueprint(crawler.bp, url_prefix='/api/crawler')
# About 始终可用
app.register_blueprint(about.bp, url_prefix='/api/about')
# AI Prompts 始终可用
app.register_blueprint(ai_prompts.ai_prompts_bp, url_prefix='/api/ai-prompts')

# 初始化邮件自动拉取调度器
def auto_fetch_emails():
    """自动拉取所有邮箱账号的邮件"""
    try:
        with app.app_context():
            from models import EmailAccount
            from services.email_service import EmailService
            
            print(f"[邮件调度器] 开始自动拉取邮件...")
            
            # 获取所有邮箱账号
            accounts = EmailAccount.query.all()
            total_accounts = len(accounts)
            success_count = 0
            
            for account in accounts:
                try:
                    # 调用拉取邮件函数
                    result = EmailService.fetch_emails_for_account(account.id)
                    if result.get('success'):
                        success_count += 1
                        print(f"[邮件调度器] 账号 {account.name} 拉取成功: {result.get('message')}")
                    else:
                        print(f"[邮件调度器] 账号 {account.name} 拉取失败: {result.get('error', '未知错误')}")
                except Exception as e:
                    print(f"[邮件调度器] 账号 {account.name} 拉取异常: {str(e)}")
                    continue
            
            print(f"[邮件调度器] 自动拉取完成: {success_count}/{total_accounts} 个账号成功")
        
    except Exception as e:
        print(f"[邮件调度器] 自动拉取异常: {str(e)}")

# 创建调度器
scheduler = BackgroundScheduler()

# 如果启用自动拉取，则添加定时任务
if Config.EMAIL_AUTO_FETCH:
    scheduler.add_job(
        func=auto_fetch_emails,
        trigger=IntervalTrigger(minutes=Config.EMAIL_FETCH_INTERVAL),
        id='auto_fetch_emails',
        name='自动拉取邮件',
        replace_existing=True
    )
    print(f"[邮件调度器] 已启动，每 {Config.EMAIL_FETCH_INTERVAL} 分钟自动拉取邮件")

# 启动调度器
scheduler.start()

# 注册关闭时停止调度器
atexit.register(lambda: scheduler.shutdown())

@app.route('/api/health', methods=['GET'])
def health_check():
    """健康检查"""
    return jsonify({
        'status': 'ok',
        'service': 'Feng Admin API Server',
        'version': '1.0.0'
    })

@app.route('/api/tools', methods=['GET'])
def list_tools():
    """列出所有可用的工具"""
    return jsonify({
        'tools': [
            {
                'name': 'User Authentication',
                'description': '用户认证系统',
                'endpoint': '/api/auth',
                'status': 'active'
            },
            {
                'name': 'Todo Management',
                'description': '待办事项管理',
                'endpoint': '/api/todos',
                'status': 'active'
            },
            {
                'name': 'Agent Management',
                'description': '智能体管理',
                'endpoint': '/api/agents',
                'status': 'active'
            },
            {
                'name': 'Note Management',
                'description': '笔记管理',
                'endpoint': '/api/notes',
                'status': 'active'
            },
            {
                'name': 'GitHub Trending',
                'description': '获取 GitHub 热门仓库',
                'endpoint': '/api/github/trending',
                'status': 'active',
                'cache': '4小时'
            },
            {
                'name': 'AI Diary',
                'description': 'AI日记工具 - 记录流水账并生成AI总结',
                'endpoint': '/api/ai_dairy',
                'status': 'active',
                'features': ['日记记录', 'AI总结', '心情分析']
            }
        ]
    })

# 示例受控路由（仅 admin 可访问）
if hasattr(globals().get('require_roles', None), '__call__') and Config.FEATURE_RBAC:
    @app.route('/api/admin/ping', methods=['GET'])
    @require_roles('admin')
    def admin_ping():
        return jsonify({'message': 'pong'}), 200

@app.route('/api/cache/clear', methods=['POST'])
def clear_cache():
    """清除所有缓存"""
    try:
        from cache_manager import CacheManager
        cache = CacheManager()
        cache.clear_all()
        return jsonify({
            'success': True,
            'message': '缓存已清除'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

@app.errorhandler(404)
def not_found(error):
    return jsonify({'error': 'Not found'}), 404

@app.errorhandler(500)
def internal_error(error):
    return jsonify({'error': 'Internal server error'}), 500

# 统一处理 HTTP 异常，返回 JSON
@app.errorhandler(HTTPException)
def handle_http_exception(error: HTTPException):
    response = {
        'error': error.name,
        'message': error.description
    }
    return jsonify(response), error.code

if __name__ == '__main__':
    # 创建数据库表
    with app.app_context():
        db.create_all()
        print("数据库表已创建")
    
    print("=" * 60)
    print("Feng Admin API Server")
    print("=" * 60)
    print(f"本地访问: http://localhost:{Config.FLASK_PORT}")
    print(f"远程访问: http://{Config.FLASK_HOST}:{Config.FLASK_PORT}")
    print(f"健康检查: http://localhost:{Config.FLASK_PORT}/api/health")
    print(f"工具列表: http://localhost:{Config.FLASK_PORT}/api/tools")
    print(f"用户认证: http://localhost:{Config.FLASK_PORT}/api/auth")
    print("-" * 60)
    print(f"数据库路径: {Config.DB_PATH}")
    print(f"缓存目录: {Config.CACHE_DIR}")
    print("=" * 60)
    app.run(host=Config.FLASK_HOST, port=Config.FLASK_PORT, debug=True)

